/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file  EthDesc.h
 * @brief Semidrive. AUTOSAR 4.3.1 MCAL Eth plugins.
 */

#ifndef ETH_DESC_RING_H_
#define ETH_DESC_RING_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "Eth.h"
#include "Compiler.h"

#define min(a,b) (((a) < (b) )? (a):(b))
enum {
    DESC_TX = 0,
    DESC_RX,
    DESC_TYPE_MAX
};

#if (ETH_DIRECT_FORWARD_ENABLE == STD_ON)
enum {
    DESC_FWD_TX = 0,
    DESC_FWD_RX,
    DESC_FWD_TYPE_MAX
};
#endif

#define GET_TX_DESC_INDEX(CtrlIdx,Ch,tdesc)  \
    ((((uint32)tdesc) - (uint32)&Eth_Desc_Buf[CtrlIdx][(Ch)][DESC_TX].desc[0])/sizeof(struct dma_desc))

#define GET_RX_DESC_INDEX(CtrlIdx,Ch,tdesc)  \
    ((((uint32)tdesc) - (uint32)&Eth_Desc_Buf[CtrlIdx][(Ch)][DESC_RX].desc[0])/sizeof(struct dma_desc))

extern VAR(dma_desc_ring_t, ETH_VAR)          \
Eth_Desc_Buf[ETH_MAXCTRLS_SUPPORTED][ETH_MAX_DMA_CHANNEL][DESC_TYPE_MAX];

#if (ETH_DIRECT_FORWARD_ENABLE == STD_ON)
extern VAR(dma_desc_ring_t, ETH_VAR)        \
Eth_Desc_Buf_Rx_Backup[ETH_DIRECT_FORWARD_NUM];
#endif

void desc_ring_init(uint8 CtrlIdx);
struct dma_desc *alloc_dma_desc(uint8 CtrlIdx, uint8 channel, boolean rx);
void free_dma_desc(uint8 CtrlIdx, uint8 channel, boolean rx);
sint32 locked_desc_put(uint8 CtrlIdx, uint8 channel, locked_desc_t *descp, boolean rx);
sint32 locked_desc_get(uint8 CtrlIdx, uint8 channel, locked_desc_t **descpp, boolean rx);
sint32 locked_desc_touch(uint8 CtrlIdx, uint8 channel, locked_desc_t **descpp, boolean rx);
struct dma_desc *get_dma_desc(uint8 CtrlIdx, uint8 channel, uint32 curidx, boolean rx);
struct dma_desc *get_dma_desc_next(uint8 CtrlIdx, uint8 channel, uint32 curidx, boolean rx);

#ifdef __cplusplus
}
#endif

#endif
